#!/usr/bin/env python3

# Francesco Conti <f.conti@unibo.it>
#
# Copyright (C) 2016-2018 ETH Zurich, University of Bologna.
# All rights reserved.

import fileinput
import argparse
import subprocess
import ipstools
import os

DEFAULT_SERVER = "https://github.com"

class tcolors:
    OK      = '\033[92m'
    WARNING = '\033[93m'
    ERROR   = '\033[91m'
    ENDC    = '\033[0m'

def execute(cmd, silent=False):
    if silent:
        stdout = devnull
    else:
        stdout = None
    return subprocess.call(cmd.split(), stdout=stdout)

parser = argparse.ArgumentParser(
    prog='CORE-V MCU generate script',
    description="""generate build/compile/synthesis scripts for CORE-V MCU""")

parser.add_argument('--vlog-args', type=str, default="",
                    help="""Pass additonal options to vlog""")
parser.add_argument('--rt-dpi', action='store_true',
                    help="""Use the PULP Runtime DPI to emulate peripherals""")
parser.add_argument('--i2c-vip', action='store_true',
                    help="""Use the i2c model (24FC1025).
                    Needs to be installed.""")
parser.add_argument('--flash-vip', action='store_true',
                    help="""Use the flash model (S25FS256).
                    Needs to be installed.""")
parser.add_argument('--i2s-vip', action='store_true',
                    help="""Use the i2s model (24FC1025).
                    Needs to be installed.""")
parser.add_argument('--verbose', action='store_true',
                    help='Show more information about commands')

args = parser.parse_args()


try:
    os.mkdir("ips")
except OSError:
    pass
# creates an IPApproX database
ipdb = ipstools.IPDatabase(
    skip_scripts=True,
    build_deps_tree=True,
    resolve_deps_conflicts=True,
    rtl_dir='rtl',
    ips_dir='ips',
    vsim_dir='sim',
    default_server=DEFAULT_SERVER,
    verbose=args.verbose
)
# updates the IPs from the git repo
ipdb.update_ips()

# launch generate-ips.py
ipdb.save_database()

execute("mkdir -p sim/vcompile/ips")
execute("rm -rf sim/vcompile/ips/*")
execute("mkdir -p sim/vcompile/rtl")
execute("rm -rf sim/vcompile/rtl/*")
execute("mkdir -p sim/vcompile/tb")
execute("rm -rf sim/vcompile/tb/*")
execute("mkdir -p fpga/core-v-mcu/tcl")
execute("rm -rf fpga/core-v-mcu/tcl/*")

execute("mkdir -p sim/ncompile/ips")
execute("rm -rf sim/ncompile/ips/*")
execute("mkdir -p sim/ncompile/rtl")
execute("rm -rf sim/ncompile/rtl/*")
execute("mkdir -p sim/ncompile/tb")
execute("rm -rf sim/ncompile/tb/*")

# creates an IPApproX database
ipdb = ipstools.IPDatabase(rtl_dir='rtl', ips_dir='ips', vsim_dir='sim',
                           load_cache=True, verbose=args.verbose)

# setting defines
if args.rt_dpi:
    ipdb.rtl_dic['tb'].sub_ips['tb'].defines = ['USE_DPI']

# handling VIPs
# assume by default that the user didn't install the proprietary VIPs so we
# remove the IP keys
if not args.i2c_vip:
    del (ipdb.rtl_dic['vip'].sub_ips['24FC1025_model'])

if not args.flash_vip:
    del (ipdb.rtl_dic['vip'].sub_ips['S25FS256_model'])

if not args.i2s_vip:
    del (ipdb.rtl_dic['vip'].sub_ips['i2s_model'])

# generate ModelSim/QuestaSim compilation scripts
ipdb.export_make(script_path="sim/vcompile/ips",
                 more_opts=args.vlog_args)
ipdb.export_make(script_path="sim/vcompile/rtl",
                 more_opts=args.vlog_args,
                 source='rtl')

# generate vsim.tcl with ModelSim/QuestaSim "linking" script
ipdb.generate_vsim_tcl("sim/tcl_files/config/vsim_ips.tcl")
ipdb.generate_vsim_tcl("sim/tcl_files/config/vsim_rtl.tcl", source='rtl')

# generate script to compile all IPs for ModelSim/QuestaSim
ipdb.generate_makefile("sim/vcompile/ips.mk")
ipdb.generate_makefile("sim/vcompile/rtl.mk", source='rtl')

# generate XCELIUM compilation scripts
ipdb.export_make(script_path="sim/ncompile/ips", simulator='ncsim')
ipdb.export_make(script_path="sim/ncompile/rtl", simulator='ncsim', source='rtl')
ipdb.generate_makefile("sim/ncompile/ips.mk")
ipdb.generate_makefile("sim/ncompile/rtl.mk", source='rtl')
ipdb.generate_ncsim_command_list(script_path="./sim/ncompile/src_ips_files.f",
                                 root='.', source='ips')
ipdb.generate_ncsim_command_list(script_path="./sim/ncompile/src_rtl_files.f",
                                 root='.', source='rtl')
# small hack to remove bad tb files until changes propagate
# this is sed -i '/tb\/tb_hwpe/d' sim/ncompile/src_ips_files.f
for line in fileinput.input("sim/ncompile/src_ips_files.f", inplace=True):
    line = line.strip('\n')
    if (not 'tb/tb_hwpe' in line and
        not 'src/axi_test' in line and
        not 'components/axi_slice_dc_master_wrap' in line and
        not 'components/axi_slice_dc_slave_wrap' in line):
        print(line)


# Generate FPGA scripts
# generate Vivado src_files.tcl
ipdb.export_vivado(script_path="fpga/core-v-mcu/tcl/ips_src_files.tcl")
ipdb.export_vivado(script_path="fpga/core-v-mcu/tcl/rtl_src_files.tcl", source='rtl')

# generate Vivado add_files.tcl
ipdb.generate_vivado_add_files("fpga/core-v-mcu/tcl/ips_add_files.tcl")
ipdb.generate_vivado_add_files("fpga/core-v-mcu/tcl/rtl_add_files.tcl", source='rtl')

# generate Vivado inc_dirs.tcl
ipdb.generate_vivado_inc_dirs("fpga/core-v-mcu/tcl/ips_inc_dirs.tcl", source='rtl')

print(tcolors.OK + "Generated new scripts for IPs!" + tcolors.ENDC)

##################################
#
# SYNTHESIS WITH DC
#
#################################
# TODO(timsaxe): We've to figure out how to make the tech specific stuff less
# intrusive.

print(tcolors.OK + "###########################################" + tcolors.ENDC)
print(tcolors.OK + "#                                         #" + tcolors.ENDC)
print(tcolors.OK + "# Generated new synthesis scripts for IPs #!" + tcolors.ENDC)
print(tcolors.OK + "#                                         #" + tcolors.ENDC)
print(tcolors.OK + "###########################################" + tcolors.ENDC)
